View Javadoc

1   /*
2    * JBCS - A JBuilder Plugin for Checkstyle
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU General Public License
6    * as published by the Free Software Foundation; either version 2
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17   *
18   * Copyright © 2003
19   * Henri Tremblay
20   */
21  package com.henri.jbcs;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.util.Properties;
27  
28  import java.awt.Event;
29  import java.awt.event.KeyEvent;
30  import javax.swing.Icon;
31  import javax.swing.ImageIcon;
32  import javax.swing.KeyStroke;
33  import javax.swing.text.Keymap;
34  
35  import com.borland.jbuilder.JBuilderToolBar;
36  import com.borland.jbuilder.node.JavaFileNode;
37  import com.borland.primetime.PrimeTime;
38  import com.borland.primetime.editor.EditorActions;
39  import com.borland.primetime.editor.EditorManager;
40  import com.borland.primetime.ide.Browser;
41  import com.borland.primetime.ide.ContentManager;
42  import com.borland.primetime.ide.ProjectView;
43  import com.borland.primetime.properties.PropertyManager;
44  import com.henri.jbcs.gui.CSPropertyGroup;
45  import com.puppycrawl.tools.checkstyle.Checker;
46  import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
47  import com.puppycrawl.tools.checkstyle.ModuleFactory;
48  import com.puppycrawl.tools.checkstyle.PackageNamesLoader;
49  import com.puppycrawl.tools.checkstyle.PropertiesExpander;
50  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
51  import com.puppycrawl.tools.checkstyle.api.Configuration;
52  
53  /***
54   *  The main class for the OpenTool.
55   *
56   * @author Henri Tremblay
57   * @version $Revision: 1.16 $ $Date: 2005/08/08 23:55:23 $
58   */
59  public class CheckStyleOpenTool
60  {
61     /*** The toolbar icon */
62     public static final Icon ICON = new ImageIcon(CheckStyleAction.class.getResource("checkmark.gif"));
63  
64     // Used by AboutOpenTools
65     // http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=17238
66     private static final String[] ABOUT_OPEN_TOOL_FIELD = {
67        "TITLE", "VERSION", "AUTHOR", "DESCRIPTION"};
68  
69     private static final String[] ABOUT_OPEN_TOOL_VALUE = {
70        "JBCS", "2.0",
71        "Henri Tremblay",
72        "Checkstyle plugin"};
73  
74     public static final String JBPROP_FILE = System.getProperty("user.home") + File.separator
75        + "jbcs.properties";
76  
77     /*** JBCS preference */
78     private static CSPreference preference;
79  
80     /*** Checker used by JBCS */
81     private static Checker checker;
82  
83     /*** Basedir of checkstyle */
84     private static String checkstyleBasedir;
85  
86     /*** MessageHandler for error messages of this class */
87     private static MessageHandler msgHandler = new MessageHandler();
88  
89     /*** Thread running checkstyle over files */
90     private static CheckerThread checkerThread = null;
91  
92     /***
93      *  The entry point of OpenTool.
94      *
95      * @param  major  Major version number
96      * @param  minor  Minor version number
97      */
98     public static void initOpenTool(byte major, byte minor) {
99        System.out.println();
100       System.out.println("  JBCS: CheckStyle 4.0 for JBuilder ");
101       System.out.println("  Checkstyle's project page: ");
102       System.out.println("  http://checkstyle.sourceforge.net");
103 
104       // Check OpenTools version number
105       if(major != PrimeTime.CURRENT_MAJOR_VERSION) {
106          return;
107       }
108 
109       // Register the property page
110       PropertyManager.registerPropertyGroup(new CSPropertyGroup());
111 
112       // Add the bindable editor action
113       CheckStyleKeymapAction keymapAction = new CheckStyleKeymapAction();
114       EditorActions.addBindableEditorAction(keymapAction);
115 
116       // Set the key shortcut
117       Keymap keymap = EditorManager.getKeymap();
118       if(keymap != null) {
119          KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, Event.SHIFT_MASK | Event.ALT_MASK);
120          keymap.addActionForKeyStroke(keyStroke, keymapAction);
121          System.out.println("Mapping JBCS to Shift+Alt+C for " + keymap.getName() + " keymap");
122       }
123       else {
124          System.err.println("Error mapping JBCS to Shift+Alt+C: No keymap found");
125       }
126 
127       // Add the Toolbar action
128       CheckStyleAction checkstyleAction = new CheckStyleAction();
129       JBuilderToolBar.GROUP_EditBar.add(checkstyleAction);
130 
131       // Add the Content Manager (Tabs above editor pane) context menu action
132       ContentManager.GROUP_NodeContext.add(checkstyleAction);
133 
134       // Add the ProjectView context menu action
135       ProjectView.registerContextActionProvider(new CheckStyleContextAction());
136    }
137 
138    /***
139     *  Retrieves information about this opentool. Used by AboutOpenTools
140     *
141     * @param  infoType  Type of information to retrieve.
142     * @return           String containing the information requested.
143     * @see <a href="http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=17238">
144     *      AboutOpenTools</a>
145     */
146    public static String getOpenToolInfo(Object infoType) {
147       String value = null;
148 
149       //loop over possible info types comparing them to the passed type
150       for(int i = 0; i < ABOUT_OPEN_TOOL_FIELD.length; i++) {
151          //if the match is found, return the corresponding info value
152          if(infoType != null && infoType.equals(ABOUT_OPEN_TOOL_FIELD[i])) {
153             value = ABOUT_OPEN_TOOL_VALUE[i];
154             break;
155          }
156       }
157       return value;
158    }
159 
160    /***
161     * Load the properties required by the plugin
162     * @return
163     */
164    private static CSPreference loadJBCSProperties() {
165 
166       try {
167          CSPreference pref = new CSPreference();
168          pref.load(JBPROP_FILE);
169          return pref;
170       }
171       catch(Exception e) {
172          msgHandler.error("JBCS failed to init. " + JBPROP_FILE + " not found", e);
173          return null;
174       }
175    }
176 
177    /***
178     * Get checkstyle properties. Might return empty properties is no file was defined
179     * @return
180     */
181    private static Properties getCheckstyleProperties() {
182       Properties p = new Properties();
183       String file = null;
184       try {
185          file = CheckStyleOpenTool.getPreference().getPropertiesFile();
186          if(file != null && file.length() != 0) {
187             p.load(new FileInputStream(file));
188          }
189       }
190       catch(IOException e) {
191          msgHandler.error("Checkstyle property file " + file + " not found: " + e, e);
192          // It doesn't matter, just return empty properties
193       }
194       return p;
195    }
196 
197    public static CSPreference getPreference() {
198       if(preference == null) {
199          preference = loadJBCSProperties();
200       }
201       return preference;
202    }
203 
204    public static void setPreference(CSPreference pref) {
205       preference = pref;
206       try {
207          preference.store(JBPROP_FILE);
208       }
209       catch(IOException ex) {
210          msgHandler.error("ERROR: Unable to save property file.", ex);
211       }
212       checker = null;
213    }
214 
215    public static synchronized Checker getChecker() {
216       if(checker == null) {
217          createChecker();
218       }
219       return checker;
220    }
221 
222    public static String getBasedir() {
223       return checkstyleBasedir;
224    }
225 
226    /***
227     * Tells if the plugin is currently running.
228     * @return if the plugin is running
229     */
230    public static boolean isRunning() {
231       return checkerThread != null && checkerThread.isAlive();
232    }
233 
234    /***
235     * Runs Checkstyle on 1 or many files in a <code>CheckerThread</code>.
236     *
237     * @param browser The Jbuilder browser where Checkstyle is launched
238     * @param nodes The files to check.
239     */
240    public static void checkNodes(Browser browser, JavaFileNode[] nodes) {
241       if(!isRunning()) {
242          msgHandler = new MessageHandler(browser);
243          checkerThread = new CheckerThread(nodes, msgHandler);
244          checkerThread.start();
245       }
246    }
247 
248    private static void createChecker() {
249 
250       msgHandler.writeStatusBarMessage("Checkstyle is initializing...");
251 
252       try {
253          CSPreference pref = getPreference();
254          if(pref == null) {
255             return;
256          }
257 
258          checker = new Checker();
259 
260          Configuration config = ConfigurationLoader.loadConfiguration(pref.getConfigurationFile(),
261             new PropertiesExpander(getCheckstyleProperties()));
262          checker.configure(config);
263 
264          // Set the basedir
265          checkstyleBasedir = checker.getBasedir();
266 
267          if(checkstyleBasedir == null) {
268             checkstyleBasedir = "";
269          }
270          else if(!checkstyleBasedir.endsWith(File.separator)) {
271             checkstyleBasedir += File.separator;
272          }
273 
274          // Get the package file
275          String packageNamefile = pref.getPackageNameFile();
276          if(packageNamefile != null && packageNamefile.length() != 0) {
277             ModuleFactory moduleFactory = PackageNamesLoader.loadModuleFactory(pref.getPackageNameFile());
278             checker.setModuleFactory(moduleFactory);
279          }
280       }
281       catch(CheckstyleException e) {
282          checker = null;
283          msgHandler.error("Can't create checker: " + e.getMessage(), e);
284       }
285    }
286 }